package com.gitee.beiding.template_excel_demo;

import com.gitee.beiding.template_excel.*;
import com.gitee.beiding.template_excel_demo.entity.Student;
import org.apache.poi.xssf.usermodel.XSSFSheet;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class ExtractDemo {
    public static void main(String[] args) throws IOException {

        /*
            本例中采用resources目录下的《数据.xlsx》作为被提取的数据源
         */
        InputStream dataInputStream = ExtractDemo.class.getClassLoader().getResourceAsStream("数据.xlsx");

        /*
            可以指定列的匹配模式
                匹配模式有三种:
                    1. ColNumberMatchingMode.EQUALS:全等匹配
                         这种模式要求数据行中的数据必须严格匹配模板行中提取表达式
                         例如:
                            数据行:    |           |  你      |好      |
                            模板行1:   |           |${/你/}   |${/好/} |
                            模板行2:   |           |${/你/}   |        |
                            模板行3:   |${/其他/}   |${/你/}   |        |

                         数据行可以匹配模板行1,无法匹配模板行2和模板行3

                    2.ColNumberMatchingMode.TEMPLATE_FULL:模板行全匹配模式
                         这种模式要求数据行中的数据能够完全满足模板行中的提取表达式
                         例如:在上例中数据行可以满足模板行1和模板行2,但是无法满足模板行3

                    3.ColNumberMatchingMode.INTERSECTION:交集匹配
                        这种模式下只要数据行和模板行至少存在一个交集即可
                        例如:在上例中数据行满足模板行1、模板行2以及模板行3

         */
        ExtractResult result = Extractor.extract(
                createTemplateSheet()//提取模板
                , dataInputStream//数据excel输入流
                , TypeMapperBuilder.createAndMapping("students[i]", Student.class).toMap(), ColNumberMatchingMode.EQUALS);//实体映射

        //从提取的结果中获取数据实体
        List<Student> list = result.get("students", List.class);

        for (Student student : list) {
            System.out.println(student);
        }

    }

    private static XSSFSheet createTemplateSheet() {

        /*
            你可以从任意存在excel的流中读取模板,但更简单快捷的方式是使用FastSheet构建一个Sheet页

            提取表达式说明:
                    1. ${xxx/regex/}是提取表达式的标准格式,xxx是接收提取结果的实体字段,regex是匹配正则
                            例如:${student.name/张伟[0-9]+/}表示将满足"张伟[0-9]+"正则的数据提取为student实体的name字段

                    2. ${xxx}是全匹配提取表达式的简写模式,该表达式将任意内容提取到xxx

                    3. ${/regex/}非获取匹配表达式,该表达式只会检验数据是否匹配regex正则,但不会保存匹配到的内容

                    4. 当对数据实体使用"[index]"作为后缀时,表明这是一个列表,引擎会将连续多行匹配的结果填充为一个列表,并自动处理一对多关系
                            例如:${students[i].name/张伟[0-9]+/}会将students创建为List<Student>
                            *注意:提取表达式不支持多维数组,并且引擎会自动忽略自增变量的名称,引擎在解析时会将自增变量抹除
                                例如:${students[i].indexs[j]}会被处理为${students[].indexs[]}
                             但是为了更好的表意性推荐将索引变化情况相同的实体使用相同名称的自增变量

            *注意:提取模板是不匹配样式的

         */
        return FastSheet.create("Sheet1")
                .newRow()
                .cell("A","序号").cell("B", "姓名").cell("C", "科目编号").cell("D", "科目")
                .newRow()
                .cell("A","${/[0-9]*/}").cell("B", "${students[i].name/张伟[0-9]+/}").cell("C", "${students[i].indexs[j]}").cell("D", "选修科目:${students[i].subjects[j]}")
                .toXSSFSheet();
    }

}
